package cc.lj.internal.coupons.application.service;

import cc.lj.internal.api.coupons.dto.command.BindTicketPackageAPICommand;
import cc.lj.internal.api.coupons.dto.command.SendPackageAPICommand;
import cc.lj.internal.api.coupons.dto.command.SendTicketsAPICommand;
import cc.lj.internal.core.exception.ServiceException;
import cc.lj.internal.coupons.application.FeignAppService;
import cc.lj.internal.coupons.domain.ticket.model.vo.TicketBatchDO;
import cc.lj.internal.coupons.domain.ticket.model.vo.TicketPackageBatchDO;
import cc.lj.internal.coupons.domain.ticket.model.vo.TicketPackageDO;
import cc.lj.internal.coupons.domain.ticket.service.ITicketBatchDomainService;
import cc.lj.internal.coupons.domain.ticket.service.ITicketPackageBatchDomainService;
import cc.lj.internal.coupons.domain.ticket.service.ITicketPackageDomainService;
import cc.lj.internal.coupons.infrastructure.excepion.CoupousExceptionEnum;
import cc.lj.internal.coupons.interfaces.dto.TicketBatchDTO;
import cc.lj.internal.coupons.interfaces.dto.TicketPackageDTO;
import cc.lj.internal.coupons.interfaces.dto.convert.TicketBatchDTOConvertDO;
import cc.lj.internal.coupons.interfaces.dto.convert.TicketMainDTOConvertDO;
import cc.lj.internal.coupons.interfaces.dto.convert.TicketPackageDTOConvertDO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.annotation.Resources;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 券包 app service
 * @author liangxifeng
 * @date 2023/8/24 10:45
 */
@Service
@Slf4j
public class TicketPackageAppService {
    //券包领域
    @Resource(name = "ticketPackageDomainServiceImpl")
    private ITicketPackageDomainService domainService;

    //券包与批次关系领域
    @Resource(name = "ticketPackageBatchDomainServiceImpl")
    private ITicketPackageBatchDomainService packageBatchDomainService;

    //券包领域
    @Resource(name = "ticketPackageDomainServiceImpl")
    private ITicketPackageDomainService packageDomainService;

    //远程请求feign
    @Resource(name = "feignAppService")
    private FeignAppService feignAppService;

    //券批次领域
    @Resource(name = "ticketBatchDomainServiceImpl")
    private ITicketBatchDomainService batchDomainService;

    /**
     * 通过主键查询券包
     * @param id
     * @return 券包DTO
     */
    public TicketPackageDTO getById(Integer id) {
        TicketPackageDO ticketPackageDO = packageDomainService.getById(id);
        return TicketPackageDTOConvertDO.INSTANCE.convert(ticketPackageDO);
    }

    /**
     * 通过主键修改券包中 关联活动状态字段
     * @param bindTicketPackageCommand
     * @return 影响行数
     */
    public Integer updateBind(BindTicketPackageAPICommand bindTicketPackageCommand) {
        //通过主键查询券包，验证如果已经关联过其他活动，则不允许继续关联
        TicketPackageDO ticketPackageDO = domainService.getById(bindTicketPackageCommand.getId());
        if(ticketPackageDO.getIsBind() == 1) {
            throw new ServiceException(CoupousExceptionEnum.PACKAGE_ISBIND);
        }
        //通过主键修改关联活动状态
        TicketPackageDO packageDO = new TicketPackageDO();
        packageDO.setId(bindTicketPackageCommand.getId());
        packageDO.setIsBind(bindTicketPackageCommand.getIsBind());
        return domainService.updateById(packageDO);
    }

    /**
     * 发券包接口
     * 1. 通过券包主键查询券包与批次关系表，获取券批次主键以及张数
     * 2. 调用domain_ticket领域层发券接口发券
     * @param sendPackageAPICommand
     * @return List<电子券使用码>
     */
    public List<String> sendPackage(SendPackageAPICommand sendPackageAPICommand) {
        //1. 通过券包主键查询券包与批次关系表，获取券批次主键以及张数
        TicketPackageBatchDO packageBatchDOParam = new TicketPackageBatchDO();
        packageBatchDOParam.setPackageId(sendPackageAPICommand.getPackageId());
        List<TicketPackageBatchDO> ticketPackageBatchDOList = packageBatchDomainService.getList(packageBatchDOParam);
        if( ticketPackageBatchDOList.size() == 0 ) {
            throw new ServiceException(CoupousExceptionEnum.GET_TICKET_PACKAGE_BACH_FAILED);
        }
        //定义存储券批次主键的map<券批次主键=>发券张数>
        Map<Integer,Integer> batchIds = new HashMap<>();
        ticketPackageBatchDOList.forEach((packageBatchDO)->{
            batchIds.put(packageBatchDO.getBatchId(),packageBatchDO.getSendNumber());
        });

        //2.调用domain_ticket发券接口发券
        SendTicketsAPICommand sendTicketsAPICommand = new SendTicketsAPICommand();
        sendTicketsAPICommand.setBatchIds(batchIds); //发券批次券
        sendTicketsAPICommand.setPackageId(sendPackageAPICommand.getPackageId()); //券包主键
        sendTicketsAPICommand.setUnionid(sendPackageAPICommand.getUnionid()); //unionid
        List<String> tickerUseCodeList = feignAppService.sendTicket(sendTicketsAPICommand);
        return tickerUseCodeList;
    }


    /**
     * 返回30条券包数据
     * @return
     */
    public List<TicketPackageDTO> getList() {
        TicketPackageDO ticketPackageDO = new TicketPackageDO();

        List<TicketPackageDO> list = domainService.getList(ticketPackageDO);
        List<TicketPackageDTO> newlist = new ArrayList<>();
        int i=0;
        for (TicketPackageDO item:list) {
            TicketPackageDTO ticketPackageDTO = TicketPackageDTOConvertDO.INSTANCE.convert(item);
            newlist.add(ticketPackageDTO);
            i++;
            //现在只返回30条数据
            if(i>=30)break;
        }
        return newlist;
    }

    /**
     * 查询券包对应的所有券批次列表
     * @param id
     * @return
     */
    public List<TicketBatchDTO> getBatchList(int id) {
        TicketPackageBatchDO ticketPackageBatchDO = new TicketPackageBatchDO();
        ticketPackageBatchDO.setPackageId(id);
        List<TicketPackageBatchDO> list = packageBatchDomainService.getList(ticketPackageBatchDO);

        List<TicketBatchDTO> newlist = new ArrayList<>();

        for(TicketPackageBatchDO item : list)
        {
            TicketBatchDO batchDO = batchDomainService.getById(item.getBatchId());
            TicketBatchDTO ticketBatchDTO = TicketBatchDTOConvertDO.INSTANCE.convert(batchDO);
            ticketBatchDTO.setSendNumber(item.getSendNumber());
            newlist.add(ticketBatchDTO);
        }
        return newlist;
    }
}
